<template>
  <div class="cesium-draw">
    <div id="cesium-drawer" />
    <div class="mouse-postion">{{ nowPostion.wgs84 }}</div>
    <div class="tool-box">
      <!-- <div class="slider-box-wrapper"><slider-box v-model:value="terrainExaggeration" :max="2" /></div> -->
      <!-- <div class="slider-box-wrapper"><slider-box v-model:value="relativeHeight" :max="10000" /></div> -->
      <div class="select-box-wrapper"><select-box :options="locationToolbarOptions" /></div>
      <div class="select-box-wrapper"><select-box :options="entityToolbarOptions" /></div>
      <div class="select-box-wrapper"><select-box :options="sizeOptions" /></div>
      <div class="select-box-wrapper"><a-checkbox v-model:checked="shadows">shadows</a-checkbox></div>
      <div class="select-box-wrapper"><a-checkbox v-model:checked="softShadows">soft shadows</a-checkbox></div>
      <div class="select-box-wrapper"><a-checkbox v-model:checked="terrainShadows">terrain shadows</a-checkbox></div>
      <div class="select-box-wrapper"><a-checkbox v-model:checked="entityShadows">entity shadows</a-checkbox></div>
      <div id="menu">
        <p><button @click="onClick('play')">播放</button></p>
        <p><button @click="onClick('stop')">暂停</button></p>
      </div>
    </div>
  </div>
</template>

<script>
//参考：Cesium深入浅出之图层管理器 https://blog.csdn.net/fywindmoon/article/details/113747843
import { DownOutlined, EditOutlined } from '@ant-design/icons-vue';
import { defineComponent, ref, watch } from 'vue';
import SliderBox from '@components/widgets/slider-box';
import SelectBox from '@components/widgets/select-box';
import * as Cesium from '@cesium/Source/Cesium.js';
import MousePosition from '@functional/utils/mousePosition';

export default defineComponent({
  name: 'shadows', // 阴影
  components: { DownOutlined, EditOutlined, SliderBox, SelectBox },
  setup() {
    return {
      viewer: null,
      setEntityShadows: ()=>{}
    };
  },
  data() {
    return {
      nowPostion: {},
      shadows: true,
      softShadows: true,
      terrainShadows: true,
      entityShadows: true,
      locationToolbarOptions: [],
      entityToolbarOptions: [],
      sizeOptions: []
    };
  },
  computed: {},
  watch: {
    shadows(val) {
      this.viewer && (this.viewer.shadows = val);
    },
    softShadows(val) {
      this.viewer && (this.viewer.shadowMap.softShadows = val);
    },
    terrainShadows(val) {
      const terrainShadows = val ? Cesium.ShadowMode.ENABLED : Cesium.ShadowMode.DISABLED;
      this.viewer && (this.viewer.terrainShadows = terrainShadows);
    },
    entityShadows(val) {
      this.setEntityShadows(val)
    }
  },
  mounted() {
    this.initViewer();
  },
  beforeUnmount() {
    if (this.viewer) {
      this.viewer.destroy();
      this.viewer = null;
    }
  },
  methods: {
    initEffects() {
      const viewer = this.viewer;

      var shadowMap = viewer.shadowMap;
      shadowMap.maximumDistance = 10000.0;

      var cesiumAir = viewer.entities.add({
        name: 'Cesium Air',
        height: 20.0,
        model: {
          uri: '//zzgis.com/cdn/3d/SampleData/models/CesiumAir/Cesium_Air.glb'
        }
      });

      var groundVehicle = viewer.entities.add({
        name: 'Ground Vehicle',
        height: 0.0,
        model: {
          uri: '//zzgis.com/cdn/3d/SampleData/models/GroundVehicle/GroundVehicle.glb',
          heightReference: Cesium.HeightReference.CLAMP_TO_GROUND
        }
      });

      var cesiumMan = viewer.entities.add({
        name: 'Cesium Man',
        height: 0.0,
        model: {
          uri: '//zzgis.com/cdn/3d/SampleData/models/CesiumMan/Cesium_Man.glb',
          heightReference: Cesium.HeightReference.CLAMP_TO_GROUND
        }
      });

      var woodTower = viewer.entities.add({
        name: 'Wood Tower',
        height: 0.0,
        model: {
          uri: '//zzgis.com/cdn/3d/SampleData/models/WoodTower/Wood_Tower.glb'
        }
      });

      var simpleCity = viewer.entities.add({
        name: 'Simple City',
        height: 0.0,
        model: {
          uri: '//zzgis.com/cdn/3d/SampleData/models/ShadowTester/Shadow_Tester_4.glb'
        }
      });

      var boxEntity = viewer.entities.add({
        name: 'Box',
        height: 10.0,
        box: {
          dimensions: new Cesium.Cartesian3(10.0, 10.0, 10.0),
          material: Cesium.Color.RED,
          shadows: Cesium.ShadowMode.ENABLED
        }
      });

      var checkerMaterial = new Cesium.CheckerboardMaterialProperty({
        evenColor: Cesium.Color.RED.withAlpha(0.5),
        oddColor: Cesium.Color.RED.withAlpha(0.0),
        repeat: new Cesium.Cartesian2(5.0, 10.0)
      });

      var checkerEntity = viewer.entities.add({
        name: 'Checkered Box',
        height: 10.0,
        box: {
          dimensions: new Cesium.Cartesian3(10.0, 10.0, 10.0),
          material: checkerMaterial,
          outline: true,
          outlineColor: Cesium.Color.RED,
          shadows: Cesium.ShadowMode.ENABLED
        }
      });

      var sphereEntity = viewer.entities.add({
        name: 'Sphere',
        height: 20.0,
        ellipsoid: {
          radii: new Cesium.Cartesian3(15.0, 15.0, 15.0),
          material: Cesium.Color.BLUE.withAlpha(0.5),
          slicePartitions: 24,
          stackPartitions: 36,
          shadows: Cesium.ShadowMode.ENABLED
        }
      });

      var locations = {
        Exton: {
          longitude: -1.31968,
          latitude: 0.698874,
          height: 74.14210186070714,
          date: 2457522.154792
        },
        HalfDome: {
          longitude: -2.086267733294987,
          latitude: 0.6587491773830219,
          height: 2640.716312584986,
          date: 2457507.247512
        },
        Everest: {
          longitude: 1.517132688,
          latitude: 0.4884844964,
          height: 8773.17824498951,
          date: 2457507.620845
        },
        PinnaclePA: {
          longitude: -1.3324415110874286,
          latitude: 0.6954224325279967,
          height: 179.14276256241743,
          date: 2457523.04162
        },
        SenecaRocks: {
          longitude: -1.3851775172879768,
          latitude: 0.6778211831093554,
          height: 682.5893300695776,
          date: 2457522.097512
        },
        Space: {
          longitude: -1.31968,
          latitude: 0.698874,
          height: 2000000.0,
          date: 2457522.154792
        }
      };

      var i;
      var entities = viewer.entities.values;
      var entitiesLength = entities.length;

      function setLocation(location) {
        var longitude = location.longitude;
        var latitude = location.latitude;
        var height = location.height;

        for (i = 0; i < entitiesLength; ++i) {
          var entity = entities[i];
          entity.position = Cesium.Cartesian3.fromRadians(longitude, latitude, height + entity.height);
        }

        viewer.clock.currentTime = new Cesium.JulianDate(location.date);
        viewer.clock.multiplier = 1.0;
      }

      function setLocationFunction(location) {
        return function() {
          setLocation(location);
        };
      }

      var locationToolbarOptions = [];
      for (var locationName in locations) {
        if (locations.hasOwnProperty(locationName)) {
          var location = locations[locationName];
          locationToolbarOptions.push({
            text: locationName,
            onselect: setLocationFunction(location)
          });
        }
      }

      this.locationToolbarOptions = locationToolbarOptions;

      function setEntity(entity) {
        for (i = 0; i < entitiesLength; ++i) {
          entities[i].show = false;
        }
        entity.show = true;
        viewer.trackedEntity = entity;
      }

      function setEntityFunction(entity) {
        return function() {
          setEntity(entity);
        };
      }

      var entityToolbarOptions = [];
      for (i = 0; i < entitiesLength; ++i) {
        var entity = entities[i];
        entityToolbarOptions.push({
          text: entity.name,
          onselect: setEntityFunction(entity)
        });
      }

      this.entityToolbarOptions = entityToolbarOptions;

      this.setEntityShadows = function(checked) {
        var entityShadows = checked ? Cesium.ShadowMode.ENABLED : Cesium.ShadowMode.DISABLED;
        for (i = 0; i < entitiesLength; ++i) {
          var entity = entities[i];
          var visual = entity.model || entity.box || entity.ellipsoid;
          visual.shadows = entityShadows;
        }
      };

      this.sizeOptions = [
        {
          text: 'Size : 2048',
          onselect: function() {
            shadowMap.size = 2048;
          }
        },
        {
          text: 'Size : 1024',
          onselect: function() {
            shadowMap.size = 1024;
          }
        },
        {
          text: 'Size : 512',
          onselect: function() {
            shadowMap.size = 512;
          }
        },
        {
          text: 'Size : 256',
          onselect: function() {
            shadowMap.size = 256;
          }
        }
      ];

      setLocation(locations.Exton);
      setEntity(cesiumAir);
    },

    onViewerInited(viewer) {
      let vm = this;
      new MousePosition(viewer, pos => {
        vm.nowPostion = pos;
      });
    },

    initViewer() {
      let vm = this;
      Cesium.Ion.defaultAccessToken = $accessToken.default;
      let osm = new Cesium.OpenStreetMapImageryProvider({
        url: 'https://a.tile.openstreetmap.org/'
      });
      let viewer = new Cesium.Viewer('cesium-drawer', {
        // imageryProvider: osm,
        terrainProvider: Cesium.createWorldTerrain(),
        contextOptions: {
          webgl: {
            alpha: true
          }
        },
        selectionIndicator: false,
        shadows: true,
        terrainShadows: Cesium.ShadowMode.ENABLED,
        animation: false, //是否显示动画控件
        baseLayerPicker: false, //是否显示图层选择控件
        geocoder: false, //是否显示地名查找控件
        // timeline: false, //是否显示时间线控件
        sceneModePicker: false, //是否显示投影方式控件
        navigationHelpButton: false, //是否显示帮助信息控件
        infoBox: false, //是否显示点击要素之后显示的信息
        fullscreenButton: false,
        shouldAnimate: true
      });

      viewer.scene.globe.depthTestAgainstTerrain = true;

      this.viewer = viewer;
      this.onViewerInited(viewer);

      this.initEffects();

      // this.viewer.flyTo(this.viewer.entities);
    },

    onClick(value) {
      switch (value) {
        case 'play':
          this.stratPlay();
          break;
        case 'stop':
          this.stopPlay();
          break;
      }
    },

    stratPlay() {
      const viewer = this.viewer;
      if (((viewer.clock.shouldAnimate = !0), this.stopTime)) {
        viewer.clock.currentTime = this.stopTime;
      } else {
        // var e = '2019-06-18';
        const t = new Date(),
          i = '00',
          a = '24',
          r = new Date(new Date(t).setHours(Number(i))),
          o = new Date(new Date(t).setHours(Number(a)));
        (viewer.scene.globe.enableLighting = !0),
          (viewer.shadows = !0),
          (viewer.clock.startTime = Cesium.JulianDate.fromDate(r)),
          (viewer.clock.currentTime = Cesium.JulianDate.fromDate(r)),
          (viewer.clock.stopTime = Cesium.JulianDate.fromDate(o)),
          (viewer.clock.clockRange = Cesium.ClockRange.LOOP_STOP),
          (viewer.clock.clockStep = Cesium.ClockStep.SYSTEM_CLOCK_MULTIPLIER),
          (viewer.clock.multiplier = 1600);
      }
    },

    stopPlay() {
      const viewer = this.viewer;
      (this.stopTime = viewer.clock.currentTime), (viewer.clock.shouldAnimate = !1);
    }
  }
});
</script>

<style lang="less">
.cesium-draw {
  position: relative;
  width: 100%;
  height: 100%;
  overflow: hidden;
  color: white;
  font-size: 14px;

  #cesium-drawer {
    width: 100%;
    height: 100%;
    overflow: hidden;
    .cesium-viewer-bottom {
      display: none !important;
    }
  }

  .mouse-postion {
    position: absolute;
    bottom: 10px;
    right: 10px;
    font-size: 14px;
    padding: 8px 12px;
    line-height: 16px;
    color: white;
    z-index: 9999;
    background-color: rgba(40, 48, 60, 1);
    border-radius: 3px;
    opacity: 0.8;
  }
}

.chart-container {
  position: absolute;
  bottom: 7px;
  left: 7px;
  background-color: rgba(0, 0, 0, 0.5);

  #profileChart {
    width: 600px;
    height: 300px;
  }
}
#canvas-a {
  top: 10px;
  display: none;
}

#canvas-b {
  top: 120px;
  display: none;
}

.tool-box {
  position: absolute;
  top: 70px;
  left: 10px;
  z-index: 9;

  #menu {
    padding-top: 20px;
    button {
      background-color: rgba(0, 0, 0, 0.75);
      border-color: rgba(0, 0, 0, 0);
      cursor: pointer;
      transition: all 500ms;
      &:hover {
        opacity: 0.75;
      }
    }
  }

  .slider-box-wrapper {
    width: 18em;
    padding: 0 10px;
    background-color: rgba(0, 0, 0, 0.75);
    margin-bottom: 10px;
  }

  .select-box-wrapper {
    padding: 5px 15px;
    background-color: rgba(0, 0, 0, 0.75);
    margin-bottom: 10px;
    width: auto;
  }
}
</style>
